<?php
namespace App\Services\WxMp;

use App\Facades\EasyWechat;
use App\Models\WxMpList;
use App\Models\WxMpOpenAuthorizer;
use Illuminate\Support\Facades\Cache;

/**
 * 微信开放平台授权应用列表
 * @package App\Services
 */
class WxMpListService
{
    const TYPE_WECHAT = 1;//服务号
    const TYPE_APPLET = 2;//小程序
    const TYPE_OPEN_PLATFORM = 3;//开放平台
    const TYPE_PAYMENT = 4;//微信支付

    protected $typeList;

    /**
     * 构造函数
     */
    public function __construct()
    {
        $this->typeList = [
            self::TYPE_WECHAT => '公众号',
            self::TYPE_APPLET => '小程序',
            self::TYPE_OPEN_PLATFORM => '开放平台',
        ];
    }

    /**
     * 获取类型列表
     * @return array
     */
    public function getTypeList()
    {
        return $this->typeList;
    }
    /**
     * 获取有效的应用列表
     * @return array
     */
    public function getValidMpList($isRefresh = false)
    {
        $cacheKey = 'wx_mp_list';
        $list = Cache::get($cacheKey);
        if (empty($list) || $isRefresh) {
            try{
                $listData = WxMpList::with('openAuthorizer')->where('is_enable', 1)->get();
                $list = $listData ? $listData->toArray() : [];
            }catch (\Exception $e){
                $list = [];
            }
            if ($list){
                Cache::put($cacheKey, $list, 60);
            }
        }
        return $list ? $list : [];
    }

    /**
     * 获取指定类型的微信应用列表
     * @param int $type
     * @return array
     */
    public function getValidMpListByType($type = self::TYPE_WECHAT)
    {
        $allValidMpList = $this->getValidMpList();
        $filterMpList = [];
        if (!empty($allValidMpList)){
            foreach ($allValidMpList as $mp){
                if ($mp['type'] == $type){
                    $filterMpList[] = $mp;
                }
            }
        }
        return $filterMpList;
    }

    /**
     * 查询指定应用ID集的有效应用列表
     * @param $appids
     * @return array
     */
    public function getValidMyListByAppids($appids)
    {
        $list = WxMpList::whereIn('appid', $appids)->where('is_enable', 1)->get();
        return $list ? $list->toArray() : [];
    }
    /**
     * 根据应用id获取有效的应用数据
     * @param $appId
     * @return array
     */
    public function getValidMpByAppid($appId)
    {
        $mp = WxMpList::where('appid', $appId)->where('is_enable', 1)->first();
        return $mp ? $mp->toArray() : [];
    }

    /**
     * 保存应用
     * @param $request
     */
    public function save($request)
    {
        \DB::beginTransaction();
        try{
            if (empty($request->id)){
                $mpModel = new WxMpList();
                $findSame = WxMpList::where('appid', $request->appid)->first();
                if ($findSame){
                    throw new \Exception('已存在改AppID的微信应用');
                }
            }else{
                $mpModel = WxMpList::findOrFail($request->id);
            }
            $mpModel->type = $request->type ?? 1;
            $mpModel->appid = $request->appid ?? '';
            $mpModel->secret = $request->secret ?? '';
            $mpModel->token = $request->token ?? '';
            $mpModel->aes_key = $request->aes_key ?? '';
            $mpModel->nick_name = $request->nick_name ?? '';
            $mpModel->head_img = $request->head_img ?? '';
            $mpModel->is_enable = $request->is_enable ?? 0;
            $mpModel->is_default = $request->is_default ?? 0;
            $mpModel->save();
            //清除其他默认
            if ($mpModel->is_default == 1){
                WxMpList::where('type', $mpModel->type)->where('id', '<>', $mpModel->id)->update(['is_default'=>0]);
            }
            //清除缓存
            $this->getValidMpList(true);
            \Db::commit();
        }catch (\Exception $e){
            \DB::rollBack();
            throw new \Exception($e->getMessage());
        }
        return true;
    }

    /**
     * 删除应用
     * @param $id
     * @return bool
     */
    public function del($id)
    {
        $find = WxMpList::findOrFail($id);
        $find->delete();
        $this->getValidMpList(true);
        return true;
    }

    /**
     * 开发平台授权信息保存
     * @param $authorizerInfo
     * @throws \Exception
     */
    public function openAuthorizerSave($authorizerInfo)
    {
        \Log::info('openAuthorizerInfo', $authorizerInfo);
        \DB::beginTransaction();
        try{
            $appid = $authorizerInfo['authorization_info']['authorizer_appid'];
            //更新授权信息表
            $wxOpenAuthorizerModel = WxMpOpenAuthorizer::FirstOrNew(
                ['appid' => $appid]
            );
            $wxOpenAuthorizerModel->appid = $authorizerInfo['authorization_info']['authorizer_appid'];
            $wxOpenAuthorizerModel->refresh_token = $authorizerInfo['authorization_info']['authorizer_refresh_token'];
            $wxOpenAuthorizerModel->nick_name = $authorizerInfo['authorizer_info']['nick_name'] ?? '';
            $wxOpenAuthorizerModel->head_img = $authorizerInfo['authorizer_info']['head_img'] ?? '';
            $wxOpenAuthorizerModel->service_type = $authorizerInfo['authorizer_info']['service_type_info']['id'] ?? 0;
            $wxOpenAuthorizerModel->verify_type = $authorizerInfo['authorizer_info']['verify_type_info']['id'] ?? 0;
            $wxOpenAuthorizerModel->user_name = $authorizerInfo['authorizer_info']['user_name'] ?? '';
            $wxOpenAuthorizerModel->alias = $authorizerInfo['authorizer_info']['alias'] ?? '';
            $wxOpenAuthorizerModel->qrcode_url = $authorizerInfo['authorizer_info']['qrcode_url'] ?? '';
            $wxOpenAuthorizerModel->signature = $authorizerInfo['authorizer_info']['signature'] ?? '';
            $wxOpenAuthorizerModel->principal_name = $authorizerInfo['authorizer_info']['principal_name'] ?? '';
            $wxOpenAuthorizerModel->authorization_state = 1;
            $wxOpenAuthorizerModel->use_state = 1;
            $wxOpenAuthorizerModel->save();
            //更新后台微信应用列表
            $wxMpList = WxMpList::FirstOrNew([
                'appid' => $wxOpenAuthorizerModel->appid,
                'is_from_open' => 1,
                'from_open_appid' => $this->appid,
            ]);
            if (empty($authorizerInfo['authorizer_info']['MiniProgramInfo'])){//空表示服务号
                $wxMpList->type = WxMpListService::TYPE_WECHAT;
            }else{//小程序
                $wxMpList->type = WxMpListService::TYPE_APPLET;
            }
            $wxMpList->appid = $wxOpenAuthorizerModel->appid;
            $wxMpList->nick_name = $wxOpenAuthorizerModel->nick_name;
            $wxMpList->head_img = $wxOpenAuthorizerModel->head_img;
            $wxMpList->open_appid = $this->appid;
            if (!empty($wxOpenAuthorizerModel->refresh_token) && $wxOpenAuthorizerModel->verify_type == 0 && $wxOpenAuthorizerModel->authorization_state == 1){
                $wxMpList->is_enable = 1;
            }else{
                $wxMpList->is_enable = 0;
            }
            $wxMpList->save();
            //刷新缓存
            $this->getValidMpList(true);
            \DB::commit();
        }catch (\Exception $e){
            \DB::rollBack();
            \Log::error($e->getMessage());
        }
    }

    /**
     * 开放平台授权取消
     * @param $appid
     * @throws \Exception
     */
    public function openAuthorizerCancel($appid)
    {
        \DB::beginTransaction();
        try{
            //更新授权信息表
            $wxOpenAuthorizerModel = WxMpOpenAuthorizer::FirstOrNew(
                ['appid' => $appid]
            );
            $wxOpenAuthorizerModel->authorization_state = 0;
            $wxOpenAuthorizerModel->save();

            //更新后台微信应用列表
            $wxMpList = WxMpList::where('appid', $wxOpenAuthorizerModel->appid)->where('is_from_open', 1)->where('from_open_appid', $this->appid)->first();
            $wxMpList->is_enable = 0;
            $wxMpList->save();
            //刷新缓存
            (new WxMpListService())->getValidMpList(true);
            \DB::commit();
        }catch (\Exception $e){
            \DB::rollBack();
            \Log::error($e->getMessage());
        }
    }
}